home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / program / p063b9s.zip / UNIT / ZRECEIVE.PAS < prev    next >
Pascal/Delphi Source File  |  1997-03-02  |  26KB  |  787 lines

  1. UNIT ZReceive;
  2. {╔══════════════════════════════════════════════════════════════════════════╗}
  3. {║ ZModem receive                                Last changed: 02.03.97  SA ║}
  4. {║                                                                          ║}
  5. {║                         (C) Copyright 1989-97 by                         ║}
  6. {║       Dan Wulff, Jens Sandalgaard, Steen Christensen & S¢ren Ager        ║}
  7. {║                                                                          ║}
  8. {║ This source may not be given to anybody, without the written permission  ║}
  9. {║ from The Portal Team.                                                    ║}
  10. {╚══════════════════════════════════════════════════════════════════════════╝}
  11. {$I POPDEFS.INC}
  12.  
  13. INTERFACE
  14.  
  15. USES Use32, Dos;
  16.  
  17. FUNCTION ZModemReceive(CONST RcvPath: PathStr; IsWaZoo: Boolean): Integer;
  18.  
  19. IMPLEMENTATION
  20.  
  21. USES OpCrt, OpDos, OpDate, OpRoot, OpString, ApTimer,
  22.      PoPTypes, Globals, ZMisc, UnixDate, MailUtil, Crc, Com, Util, FileUtil,
  23.      TransVid, NetFile, SimpDB, LogFile, MTask, StrUtil;
  24.  
  25.   FUNCTION ZModemReceive;
  26.   CONST
  27.     ZAttnLen              = 33;
  28.  
  29.   VAR
  30.     Attn                  : S34;
  31.     OutFile               : FILE;
  32.     CanDo32,
  33.     IsBinary, EOFSeen     : Boolean;
  34.     i, TryZHdrType, ZConv : Integer;
  35.     UploadPath            : PathStr;
  36.     RxCount, FileStart,
  37.     RxBytes, DiskAvail,
  38.     RemoteSize,
  39.     RemoteTime            : LongInt;
  40.     buf                   : Pointer;
  41.     RemoteName            : String;
  42.     ReceiveMax            : Word;
  43.     t                     : EventTimer;
  44.  
  45.     PROCEDURE RZAckBibi;
  46.     VAR
  47.       n              : Byte;
  48.       c              : Integer;
  49.     BEGIN
  50. {$IFDEF ZDebug}
  51.       FastWrite('RZAckBibi             ',1,1,7);
  52. {$ENDIF}
  53.       ZPutLongIntoHeader(0, TxHdr);
  54.       {  FPurgeIn;}
  55.       FOR n:=4 DOWNTO 1 DO
  56.       BEGIN
  57.         ZSendHexHeader(ZFIN, TxHdr);
  58.         CASE ZGetByte(100) OF
  59.           79 : BEGIN
  60.                  c:=ZGetByte(5);
  61.                  ComPort^.PurgeIn;
  62.                  Exit;
  63.                END;
  64.           TimeOut,
  65.           RCDO : Exit;
  66.         END;
  67.       END;
  68.     END;
  69.  
  70.     FUNCTION RZSaveToDisk(VAR RxBytes : LongInt) : Integer;
  71.     LABEL
  72.       Oops;
  73.     VAR
  74.       RealCount,i : Integer;
  75.     BEGIN
  76. {$IFDEF ZDebug}
  77.       FastWrite('RZSaveToDisk      ',1,1,7);
  78. {$ENDIF}
  79.       IF GotESC THEN
  80.       BEGIN
  81.         ZSendCan;
  82.         REPEAT
  83.           i:=ZGetByte(20);
  84.           ComPort^.PurgeIn;
  85.         UNTIL (i=TimeOut) OR (i=RCDO);
  86.         ZSendCan;
  87.         ShowError('Keyboard ESC',False,true,false);
  88.         RZSaveToDisk:=Error;
  89.         Exit;
  90.       END;
  91.       {IF RxBytes<>ZSize THEN WriteLn(ZSize);}
  92. {
  93.       IF IsBinary THEN
  94.       BEGIN
  95. }
  96.         BlockWrite(OutFile, buf^, RxCount, RealCount);
  97.         IF RxCount<>RealCount THEN GOTO Oops;
  98. {
  99.       END ELSE
  100.       BEGIN
  101.         ShowError('Text NOT implemented',True,false,false);
  102.       END;
  103. }
  104.       Inc(RxBytes, RxCount);
  105.       ShowBlockSize(RxCount,false);
  106.       ShowCurrentByte(RxBytes,false);
  107.       RZSaveToDisk:=ok;
  108.       Exit;
  109.   Oops:
  110.       ShowError('Error writing filedata',True,true,false);
  111.       RZSaveToDisk:=Error;
  112.     END;
  113.  
  114.     FUNCTION RZGetHeader : Integer;
  115.     VAR
  116.       Net, Node, IORes : Integer;
  117.       Found     : Boolean;
  118.       OurName   : PathStr;
  119.       p,n       : Byte;
  120.       s         : String;
  121.       Srec      : SEARCHREC;
  122.       ud, power : LongInt;
  123.       Dt        : DateTime;
  124.       BadWaZOOFile   : PSimpDB;
  125.       BadWaZooRec    : TBadWaZOO;
  126. {$IFDEF DateDebug}
  127.       FName : PathStr;
  128.       f : File;
  129. {$ENDIF}
  130.     BEGIN
  131. {$IFDEF ZDebug}
  132.       FastWrite('RZGetHeader              ',1,1,7);
  133. {$ENDIF}
  134. {     IF (Not RXBINARY) and (ZConv=ZCNL) THEN IsBinary:=False ELSE IsBinary:=True;}
  135.       IsBinary:=True;
  136.       RemoteSize:=0;
  137.       RemoteTime:=0;
  138.       RemoteName:='';
  139.       p:=0;
  140.       WHILE (p<RxCount) AND (BufAry(Buf^)[p]<>0) DO
  141.       BEGIN
  142.         RemoteName:=RemoteName+Char(BufAry(Buf^)[p]);
  143.         Inc(p);
  144.       END;
  145.       Inc(p);
  146.       RemoteName:=StUpCase(JustFileName(RemoteName));
  147.       Replace(RemoteName, ' ', '_', 0);
  148.       OurName:=RemoteName;
  149.       WHILE (p<RxCount) AND (Char(BufAry(Buf^)[p])<>' ') AND (BufAry(Buf^)[p]<>0) DO
  150.       BEGIN
  151.         RemoteSize:=(RemoteSize * 10)+BufAry(Buf^)[p] - $30;
  152.         Inc(p);
  153.       END;
  154.       IF RemoteSize+10240>DiskAvail THEN
  155.       BEGIN
  156.         ShowError('Disk space',True,true,false);
  157.         RZGetHeader:=Error;
  158.         Exit;
  159.       END;
  160.       Inc(p);
  161.       s:='';
  162.       WHILE (p<RxCount) AND (BufAry(Buf^)[p] IN [$30..$37]) DO
  163.       BEGIN
  164.         s:=s+Char(BufAry(Buf^)[p]);
  165.         Inc(p);
  166.       END;
  167.       ud:=0;
  168.       power:=1;
  169.       FOR n:=Length(s) DOWNTO 1 DO
  170.       BEGIN
  171.         ud:=ud+(Ord(s[n])-$30)*power;
  172.         power:=power*8;
  173.       END;
  174. {$IFDEF DateDebug}
  175.       FName:=StartPath+ForceExtension(RemoteName, 'DMP');
  176.       if ud>788400000 then addlog('!', 'DATE ERROR: '+FName);
  177.       assign(f, fname); rewrite(f, 1);
  178.       blockwrite(f, buf^, RxCount);
  179.       close(f);
  180. {$ENDIF}
  181.       WITH Dt DO
  182.         UnpackUnix(ud, Year, Month, Day, Hour, Min, Sec);
  183.       packtime(Dt, RemoteTime);
  184.  
  185.       Found:=False;
  186.       IF IsWaZoo THEN
  187.       BEGIN
  188.         IF (Copy(RemoteName,9,4)='.REQ') And (Str2Int('$'+Copy(RemoteName,1,4),Net)) And
  189.            (Str2Int('$'+Copy(RemoteName,5,4),Node)) THEN
  190.         BEGIN
  191.           RemoteName:=JustFileName(MakeReqFileName(Net, Node, GlobNodeStat));
  192.           OurName:=RemoteName;
  193.         END ELSE
  194.         BEGIN
  195.           New(BadWaZOOFile, Open(StartPath+PoPBadWaZooFileName, SizeOf(TBadWaZoo), False));
  196.           IF BadWaZOOFile<>Nil THEN
  197.           BEGIN
  198.             WHILE NOT Found AND BadWaZOOFile^.NextRec(BadWaZOORec, Keep) DO
  199.             BEGIN
  200.               IF CmpAdr(BadWaZooRec.Address, Call) AND
  201.                  (StUpCase(BadWaZooRec.FName)=StUpCase(RemoteName)) THEN
  202.                 Found:=True
  203.               ELSE
  204.                 BadWaZooFile^.Unlock(BadWaZooFile^.FilePos-1);
  205.             END;
  206.             IF Found THEN
  207.             BEGIN
  208.               BadWaZooFile^.DelRec(BadWaZooRec, BadWaZOOFile^.FilePos-1);
  209.             END;
  210.             Dispose(BadWaZOOFile, Close);
  211.             Found:=((Found) AND (BadWaZooRec.FSize=RemoteSize) AND (BadWaZooRec.FTime=RemoteTime))
  212.           END;
  213.           IF Found THEN
  214.           BEGIN
  215.             RenameFile(UploadPath+BadWaZooRec.NewName, UploadPath+RemoteName);
  216.           END ELSE
  217.           BEGIN
  218.             FINDFIRST(UploadPath+RemoteName, AnyFile, Srec);
  219.             IF DOSError=0 THEN
  220.             BEGIN
  221.               IF (SRec.Size=RemoteSize) AND (RemoteTime=SRec.Time) THEN
  222.               BEGIN
  223.                 ShowError('Already have: '+RemoteName+', skipping', False, True, False);
  224.                 RZGetHeader:=ZSKIP;
  225.                 FindClose(SRec);
  226.                 Exit;
  227.               END;
  228.               RemoteName:=JustFileName(UniqueName(UploadPath+RemoteName));
  229.             END;
  230.             FindClose(SRec);
  231.           END;
  232.         END;
  233.       END ELSE
  234.       BEGIN
  235.         FindFirst(UploadPath+RemoteName,AnyFile,SRec);
  236.         IF (DosError=0) And ((SRec.Size>RemoteSize) or (SRec.Time<>RemoteTime)) THEN
  237.           RemoteName:=JustFileName(UniqueName(UploadPath+RemoteName));
  238.         FindClose(SRec);
  239.       END;
  240.       IF OurName<>RemoteName THEN ShowError('File renamed from: '+OurName+' to: '+RemoteName, False, True, False);
  241.       Assign(OutFile, UploadPath+RemoteName); FileMode:=ShareRW+ShareDenyRW;
  242.       Reset(OutFile, 1);
  243.       IORes:=IoResult;
  244.       IF IoRes<>0 THEN Rewrite(OutFile, 1);
  245.       IORes:=IoResult;
  246.       IF IoRes<>0 THEN
  247.       BEGIN
  248.         ShowError('Error ('+Long2Str(IoRes)+') creating file: '+UploadPath+RemoteName,True,true,false);
  249.         RZGetHeader:=Error;
  250.         Exit;
  251.       END;
  252.  
  253.       { Check for TTY }
  254.  
  255.       FileStart:=FileSize(OutFile);
  256.       Seek(OutFile, FileStart);
  257.  
  258.       ShowCurrentFileName(RemoteName,FileStart,RemoteSize,96,false);
  259.       RZGetHeader:=ok;
  260.     END;
  261.  
  262.     FUNCTION RZ32ReceiveData(buf : Pointer; MaxLength : Word) : Integer;
  263.     LABEL
  264.       CrcFoo;
  265.     VAR
  266.       Crc32 : LongInt;
  267.       d, c  : Integer;
  268.       x     : Byte;
  269.     BEGIN
  270. {$IFDEF ZDebug}
  271.       FastWrite('RZ32ReceiveData          ',1,1,7);
  272. {$ENDIF}
  273.       Crc32:=$ffffffff; RxCount:=0;
  274.       WHILE RxCount <= MaxLength DO
  275.       BEGIN
  276.         c:=ZGetZDL;
  277.         IF Hi(c)<>0 THEN
  278.         BEGIN
  279. CrcFoo:
  280.           CASE c OF
  281.             GOTCRCE,
  282.             GOTCRCG,
  283.             GOTCRCQ,
  284.             GOTCRCW : BEGIN
  285.                         d:=c;
  286.                         Crc32:=UpdCrc32(Lo(c), Crc32);
  287.                         FOR x:=1 TO 4 DO
  288.                         BEGIN
  289.                           c:=ZGetZDL;
  290.                           IF Hi(c)<>0 THEN GOTO CrcFoo;
  291.                           Crc32:=UpdCrc32(Lo(c), Crc32);
  292.                         END;
  293.                         IF Crc32<>$debb20e3 THEN
  294.                         BEGIN
  295.                           ShowError('CRC error ',True,false,false);
  296.                           Pause(50);
  297.                           RZ32ReceiveData:=Error;
  298.                           Exit;
  299.                         END;
  300.                         RZ32ReceiveData:=d;
  301.                       END;
  302.             GOTCAN : BEGIN
  303.                        ShowError('Cancelled',False,true,false);
  304.                        RZ32ReceiveData:=ZCAN;
  305.                      END;
  306.             TimeOut : BEGIN
  307.                         ShowError('TimeOut1',True,false,false);
  308.                         RZ32ReceiveData:=c;
  309.                       END;
  310.             RCDO : BEGIN
  311.                      ShowError('Lost Carrier',True,false,false);
  312.                      ComPort^.PurgeIn;
  313.                      RZ32ReceiveData:=c;
  314.                    END;
  315.           ELSE BEGIN
  316.               ShowError('Debris ['+HexW(Word(c))+']',True,false,false);
  317.               ComPort^.PurgeIn;
  318.               RZ32ReceiveData:=c;
  319.             END;
  320.           END;
  321.           Exit;
  322.         END;
  323.  
  324.         BufAry(Buf^)[RxCount]:=Lo(c);
  325.         Inc(RxCount);
  326.         Crc32:=UpdCrc32(Lo(c), Crc32);
  327.       END;
  328.       ShowError('Long pkt',True,false,false);
  329.       RZ32ReceiveData:=Error;
  330.     END;
  331.  
  332.     FUNCTION RZReceiveData(buf : Pointer; MaxLength : Word) : Integer;
  333.     LABEL
  334.       CrcFoo;
  335.     VAR
  336.       c, d           : Integer;
  337.       Crc16          : Word;
  338.     BEGIN
  339. {$IFDEF ZDebug}
  340.       FastWrite('RZReceiveData              ',1,1,7);
  341. {$ENDIF}
  342.       IF RxFrameInd=ZBIN32 THEN
  343.       BEGIN
  344.         CanDo32:=True;
  345.         ShowErrorCheckingMethod('Z-Receive CRC32',false);
  346.         RZReceiveData:=RZ32ReceiveData(buf, MaxLength);
  347.         Exit;
  348.       END;
  349.       CanDo32:=False;
  350.       ShowErrorCheckingMethod('Z-Receive CRC16',false);
  351.       Crc16:=0; RxCount:=0;
  352.       WHILE RxCount <= MaxLength DO
  353.       BEGIN
  354.         c:=ZGetZDL;
  355.         IF Hi(c)<>0 THEN
  356.         BEGIN
  357. CrcFoo:
  358.           CASE c OF
  359.             GOTCRCE,
  360.             GOTCRCG,
  361.             GOTCRCQ,
  362.             GOTCRCW : BEGIN
  363.                         d:=c;
  364.                         Crc16:=UpdCrc16(Lo(c), Crc16);
  365.                         c:=ZGetZDL;
  366.                         IF Hi(c)>0 THEN GOTO CrcFoo;
  367.                         Crc16:=UpdCrc16(Lo(c), Crc16);
  368.                         c:=ZGetZDL;
  369.                         IF Hi(c)>0 THEN GOTO CrcFoo;
  370.                         Crc16:=UpdCrc16(Lo(c), Crc16);
  371.                         IF Crc16<>0 THEN
  372.                         BEGIN
  373.                           ShowError('CRC Error',True,false,false);
  374.                           RZReceiveData:=Error;
  375.                           Exit;
  376.                         END;
  377.                         RZReceiveData:=d;
  378.                       END;
  379.             GOTCAN : BEGIN
  380.                        ShowError('Cancelled',False,false,false);
  381.                        RZReceiveData:=ZCAN;
  382.                      END;
  383.             TimeOut : BEGIN
  384.                         ShowError('TimeOut2',True,false,false);
  385.                         RZReceiveData:=c;
  386.                       END;
  387.             RCDO : BEGIN
  388.                      ShowError('No Carrier',True,true,false);
  389.                      ComPort^.PurgeIn;
  390.                      RZReceiveData:=c;
  391.                    END;
  392.           ELSE BEGIN
  393.               ShowError('Debris ['+HexW(Word(c))+']',True,false,false);
  394.               ComPort^.PurgeIn;
  395.               RZReceiveData:=c;
  396.             END;
  397.           END;                      { case }
  398.           Exit;
  399.         END;
  400.         BufAry(Buf^)[RxCount]:=Byte(c);
  401.         Inc(RxCount);
  402.         Crc16:=UpdCrc16(Lo(c), Crc16);
  403.       END;
  404.       ShowError('Long pkt',True,false,false);
  405.       RZReceiveData:=Error;
  406.     END;
  407.  
  408.     FUNCTION RZReceiveFile : Integer;
  409.     LABEL
  410.       Cont, NxtHdr, MoreData, Err;
  411.     VAR
  412.       c, n         : Integer;
  413.       SPtr         : String;
  414.     BEGIN
  415. {$IFDEF ZDebug}
  416.       FastWrite('RZeceiveFile              ',1,1,7);
  417. {$ENDIF}
  418.       EOFSeen:=False;
  419.       c:=RZGetHeader;
  420.       IF (c=Error) OR (c=ZSKIP) THEN
  421.       BEGIN
  422.         IF c=ZSKIP THEN TryZHdrType:=ZSKIP;
  423.         RZReceiveFile:=c;
  424.         Exit;
  425.       END;
  426.       n:=10;
  427.       RxBytes:=FileStart;
  428.       WHILE True DO
  429.       BEGIN
  430. Cont:
  431.         ZPutLongIntoHeader(RxBytes, TxHdr);
  432.         ZSendHexHeader(ZRPOS, TxHdr);
  433. NxtHdr:
  434.         c:=ZGetHeader(RxHdr);
  435.         CASE c OF
  436.           ZDATA : BEGIN
  437.                     IF RxPos<>RxBytes THEN
  438.                     BEGIN
  439.                       Dec(n);
  440.                       IF n=0 THEN
  441.                       BEGIN
  442.                         SPtr:='FuBar';
  443.                         GOTO Err;
  444.                       END;
  445.                       ShowError('Bad pos: '+Long2Str(RxBytes)+' '+Long2Str(RxPos),True,false,false);
  446.                       ZPutString(Attn);
  447.                       GOTO Cont;
  448.                     END;
  449. MoreData:
  450.                     c:=RZReceiveData(buf, ReceiveMax);
  451.                     CASE c OF
  452.                       ZCAN : BEGIN
  453.                                SPtr:='Cancelled';
  454.                                GOTO Err;
  455.                              END;
  456.                       RCDO : BEGIN
  457.                                SPtr:='Carrier';
  458.                                ComPort^.PurgeIn;
  459.                                GOTO Err;
  460.                              END;
  461.                       Error : BEGIN
  462.                                 Dec(n);
  463.                                 IF n=0 THEN
  464.                                 BEGIN
  465.                                   SPtr:='FUBAR';
  466.                                   GOTO Err;
  467.                                 END;
  468.                                 ShowError('Pos Error: '+Long2Str(RxBytes)+' Retries: '+Long2Str(n),True,false,false);
  469.                                 ZPutString(Attn);
  470.                                 {continue}
  471.                               END;
  472.                       TimeOut : BEGIN
  473.                                   Dec(n);
  474.                                   IF n=0 THEN
  475.                                   BEGIN
  476.                                     SPtr:='TimeOut3';
  477.                                     GOTO Err;
  478.                                   END;
  479.                                   ShowError('TimeOut at: '+Long2Str(RxBytes)+'  Retries: '+Long2Str(n),True,false,false);
  480.                                 END;
  481.                       GOTCRCW,
  482.                       GOTCRCQ : BEGIN
  483.                                   n:=10;
  484.                                   IF RZSaveToDisk(RxBytes)=Error THEN
  485.                                   BEGIN
  486.                                     RZReceiveFile:=Error;
  487.                                     Exit;
  488.                                   END;
  489.                                   ZPutLongIntoHeader(RxBytes, TxHdr);
  490.                                   ZSendHexHeader(ZACK, TxHdr);
  491.                                   IF c=GOTCRCQ THEN GOTO MoreData
  492.                                   ELSE GOTO NxtHdr;
  493.                                 END;
  494.                       GOTCRCG,
  495.                       GOTCRCE : BEGIN
  496.                                   n:=10;
  497.                                   IF RZSaveToDisk(RxBytes)=Error THEN
  498.                                   BEGIN
  499.                                     RZReceiveFile:=Error;
  500.                                     Exit;
  501.                                   END;
  502.                                   IF c=GOTCRCE THEN GOTO NxtHdr
  503.                                   ELSE GOTO MoreData;
  504.                                 END;
  505.                     END;            { case }
  506.                   END;              { case zdata}
  507.           ZNAK,
  508.           TimeOut : BEGIN
  509.                       Dec(n);
  510.                       IF n=0 THEN
  511.                       BEGIN
  512.                         SPtr:='Garbled packet';
  513.                         GOTO Err;
  514.                       END;
  515.                       ShowError('TimeOut at: '+Long2Str(RxBytes)+'  Retries: '+Long2Str(n),True,false,false);
  516.                     END;
  517.           ZFILE : BEGIN
  518.                     c:=RZReceiveData(buf, ReceiveMax);
  519.                   END;
  520.           ZEOF : BEGIN
  521.                    IF RxPos<>RxBytes THEN GOTO NxtHdr;
  522.                    SetFTime(OutFile, RemoteTime);
  523.                    Close(OutFile);
  524.                    IF IoResult<>0 THEN ShowError('Error closing file',True,true,false);
  525.                    FileReceived(RemoteName,'Z'+CrcStr(CanDo32),FALSE);
  526.                    RZReceiveFile:=c;
  527.                    Exit;
  528.                  END;
  529.           Error : BEGIN
  530.                     Dec(n);
  531.                     IF n=0 THEN
  532.                     BEGIN
  533.                       SPtr:='HdrJunk';
  534.                       GOTO Err;
  535.                     END;
  536.                     ShowError('Pos Error: '+Long2Str(RxBytes)+' Retries: '+Long2Str(n),True,false,false);
  537.                     ZPutString(Attn);
  538.                   END;
  539.           ZSKIP : BEGIN
  540.                     RZReceiveFile:=c;
  541.                     Exit;
  542.                   END;
  543.         ELSE BEGIN
  544.             SPtr:='Que WHAT??!';
  545.             ComPort^.PurgeIn;
  546.             GOTO Err;
  547.           END;
  548.         END;                        {case}
  549.  
  550.       END;                          { while }
  551. Err:
  552.       ShowError('Z-rz '+SPtr,True,true,false);
  553.       RZReceiveFile:=Error;
  554.     END;
  555.  
  556.     FUNCTION RZInitReceiver : Integer;
  557.     LABEL
  558.       Again, Err;
  559.     VAR
  560.       n, errors : ShortInt;
  561.       SPtr      : String;
  562.     BEGIN
  563. {$IFDEF ZDebug}
  564.       FastWrite('RZInitReceiver              ',1,1,7);
  565. {$ENDIF}
  566.       n:=12;
  567.       errors:=0;
  568.       FillChar(Attn, SizeOf(Attn), 0);
  569.       WHILE n >= 0 DO
  570.       BEGIN
  571. Again:
  572.         ZPutLongIntoHeader(0, TxHdr);
  573.         TxHdr[ZF0]:=CANFC32 OR CANFDX OR CANOVIO;
  574.         ZSendHexHeader(TryZHdrType, TxHdr);
  575.         IF (TryZHdrType=ZSKIP) THEN TryZHdrType:=ZRINIT;
  576.         CASE ZGetHeader(RxHdr) OF
  577.           ZFILE : BEGIN
  578.                     ZConv:=RxHdr[ZF0];
  579.                     TryZHdrType:=ZRINIT;
  580.                     IF RZReceiveData(buf, ReceiveMax)=GOTCRCW THEN
  581.                     BEGIN
  582.                       RZInitReceiver:=ZFILE;
  583.                       Exit;
  584.                     END;
  585.                     ZSendHexHeader(ZNAK, TxHdr);
  586.                     Dec(n);
  587.                     IF n=0 THEN
  588.                     BEGIN
  589.                       SPtr:='ZFILE';
  590.                       GOTO Err;
  591.                     END;
  592.                     GOTO Again;
  593.                   END;
  594.           ZSINIT : BEGIN
  595.                      IF RZReceiveData(@Attn[1], ZAttnLen)=GOTCRCW THEN
  596.                      BEGIN
  597.                        ZPutLongIntoHeader(0, TxHdr);
  598.                        ZSendHexHeader(ZACK, TxHdr);
  599.                        Exit;
  600.                      END;
  601.                      i:=1;
  602.                      WHILE (Attn[i]<>#0) And (i<255) DO
  603.                        Inc(i);
  604.                      Attn[0]:=Char(i-1);
  605.                      ZSendHexHeader(ZNAK, TxHdr);
  606.                      Dec(n);
  607.                      IF n=0 THEN
  608.                      BEGIN
  609.                        SPtr:='ZSINIT';
  610.                        GOTO Err;
  611.                      END;
  612.                      GOTO Again;
  613.                    END;
  614.           ZFREECNT : BEGIN
  615.                        ZPutLongIntoHeader(DiskAvail, TxHdr);
  616.                        ZSendHexHeader(ZACK, TxHdr);
  617.                        GOTO Again;
  618.                      END;
  619.           ZCOMMAND : BEGIN
  620.                        IF RZReceiveData(buf, ReceiveMax)=GOTCRCW THEN
  621.                        BEGIN
  622.                          ShowError('Ignoring ?? ',False,false,false);
  623.                          ZPutLongIntoHeader(0, TxHdr);
  624.                          REPEAT
  625.                            ZSendHexHeader(ZCOMPL, TxHdr);
  626.                            Inc(errors);
  627.                          UNTIL (errors >= 10) OR (ZGetHeader(RxHdr)=ZFIN);
  628.                          RZAckBibi;
  629.                          RZInitReceiver:=ZCOMPL;
  630.                          Exit;
  631.                        END ELSE
  632.                          ZSendHexHeader(ZNAK, TxHdr);
  633.                        Dec(n);
  634.                        IF n=0 THEN
  635.                        BEGIN
  636.                          SPtr:='CMD';
  637.                          GOTO Err;
  638.                        END;
  639.                        GOTO Again;
  640.                      END;
  641.           ZCOMPL : BEGIN
  642.                      Dec(n);
  643.                      IF n=0 THEN
  644.                      BEGIN
  645.                        SPtr:='COMPL';
  646.                        GOTO Err;
  647.                      END;
  648.                      GOTO Again;
  649.                    END;
  650.           ZFIN : BEGIN
  651.                    RZAckBibi;
  652.                    RZInitReceiver:=ZCOMPL;
  653.                    Exit;
  654.                  END;
  655.           ZCAN : BEGIN
  656.                    SPtr:='CAN';
  657.                    GOTO Err;
  658.                  END;
  659.           RCDO : BEGIN
  660.                    SPtr:='CARRIER';
  661.                    ComPort^.PurgeIn;
  662.                    GOTO Err;
  663.                  END;
  664.  
  665.         END;                        {case}
  666.         Dec(n);
  667.       END;                          { while }
  668.       SPtr:='TIME';
  669. Err:
  670.       ShowError('Z-InitRecv '+SPtr,True,true,false);
  671.       RZInitReceiver:=Error;
  672.     END;
  673.  
  674.     FUNCTION RZReceiveBatch : Integer;
  675.     VAR
  676.       UName : PathStr;
  677.       c     : Integer;
  678.       Found : Boolean;
  679.       BadWaZOOFile   : PSimpDB;
  680.       BadWaZooRec    : TBadWaZOO;
  681.     BEGIN
  682. {$IFDEF ZDebug}
  683.       FastWrite('RZReceiveBatch        ',1,1,7);
  684. {$ENDIF}
  685.       WHILE True DO
  686.       BEGIN
  687.         c:=RZReceiveFile;
  688.         CASE c OF
  689.           ZEOF,
  690.           ZSKIP : BEGIN
  691.                     CASE RZInitReceiver OF
  692.                       ZCOMPL : BEGIN
  693.                                  RZReceiveBatch:=ok;
  694.                                  Exit;
  695.                                END;
  696.                       ZFILE : ;
  697.                       ELSE     BEGIN
  698.                                  RZReceiveBatch:=Error;
  699.                                  Exit;
  700.                                END;
  701.                     END;
  702.                   END;
  703.           ELSE    BEGIN
  704.                     SetFTime(OutFile, RemoteTime);
  705.                     Found:=(FileSize(OutFile)>0);
  706.                     Close(OutFile);
  707.                     IF NOT Found THEN
  708.                       Erase(OutFile)
  709.                     ELSE
  710.                       IF IsWaZoo THEN
  711.                       BEGIN
  712.                         AddLog('!','File '+RemoteName+' aborted - saving resume information');
  713.                         UName:=UniqueName(UploadPath+'BADWAZOO.000');
  714.                         RenameFile(UploadPath+RemoteName, UName);
  715.                         New(BadWaZOOFile, Open(StartPath+PoPBadWaZooFileName, SizeOf(TBadWaZoo), True));
  716.                         IF BadWaZooFile<>NIL THEN
  717.                         BEGIN
  718.                           FillChar(BadWaZooRec, SizeOf(BadWaZooRec), 0);
  719.                           WITH BadWaZooRec DO
  720.                           BEGIN
  721.                             Address:=Call;
  722.                             FName:=RemoteName;
  723.                             FSize:=RemoteSize;
  724.                             FTime:=RemoteTime;
  725.                             NewName:=StUpCase(JustFileName(UName));
  726.                             NodeStat:=GlobNodeStat;
  727.                           END;
  728.                           BadWaZooFile^.AddRec(BadWazooRec);
  729.                           Dispose(BadWaZooFile, Close);
  730.                         END ELSE
  731.                           AddLog('!', 'Not enough memory to open: '+PoPBadWaZooFileName+' resume information NOT saved');
  732.                       END;
  733.                     RZReceiveBatch:=c;
  734.                     Exit;
  735.                   END;
  736.         END;                        { case }
  737.       END;                          { while }
  738.     END;
  739.  
  740.   BEGIN
  741. {$IFDEF ZDebug}
  742.     FastWrite('ZModemReceive           ',1,1,7);
  743. {$ENDIF}
  744.  
  745. {   FSetBrk(Off);
  746.     FSetBrk(On);}
  747.  
  748.     ReceiveMax:=32768;
  749.     RxTimeOut:=100;
  750.     TryZHdrType:=ZRINIT;
  751.  
  752.     UploadPath:=RcvPath;
  753.     UploadPath:=AddBackSlash(UploadPath);
  754.  
  755.     DiskAvail:=DriveFree(Ord(Upcase(RcvPath[1])) - Ord('A')+1);
  756.     IF NOT GetMemCheck(buf, 8192) THEN
  757.     BEGIN
  758.       ShowError('Not enough memory',True,true,false);
  759.       ZModemReceive:=Error;
  760.       Exit;
  761.     END;
  762.     FillChar(buf^, 8192, 0);
  763.     ComPort^.PurgeIn; ComPort^.PurgeOut;
  764.     i:=RZInitReceiver;
  765.     IF (i=ZCOMPL) OR ((i=ZFILE) AND (RZReceiveBatch=ok)) THEN
  766.     BEGIN
  767. {   FSetBrk(Off);
  768.     FSetBrk(On);}
  769.       FreeMem(buf, 8192);
  770.       ZModemReceive:=ZTRUE;
  771.       ShowError('Transfer completed', False, False, False);
  772.       Exit;
  773.     END;
  774.     ShowError('Transfer aborted', False, True, False);
  775.     ComPort^.PurgeOut;
  776.     ComPort^.SetXOn(Off);
  777.     ZSendCan;
  778.     NewTimerSecs(t, 2);
  779.     WHILE (NOT TimerExpired(t)) AND (NOT ComPort^.OutEmpty) AND (ComPort^.Carrier) DO
  780.       GiveUpTime;
  781. {   FSetBrk(On);}
  782.     FreeMem(buf, 8192);
  783.     ZModemReceive:=ZFALSE;
  784.   END;
  785.  
  786. END.
  787.